package com.vincent.template.service.logic.impl;

import com.google.common.collect.Lists;
import com.vincent.template.commons.exception.Vct520Exception;
import com.vincent.template.domain.SysAuthPo;
import com.vincent.template.dto.sys.auth.AuthDto;
import com.vincent.template.repository.SysAuthRepository;
import com.vincent.template.repository.SysBindAuthGroupAuthRepository;
import com.vincent.template.repository.SysBindAuthUriRepository;
import com.vincent.template.repository.SysBindRoleAuthRepository;
import com.vincent.template.service.logic.AuthService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Vincent Wang
 * @date 2021/3/25 17:37
 */
@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private SysAuthRepository authRepository;
    @Autowired
    private SysBindAuthGroupAuthRepository bindAuthGroupAuthRepository;
    @Autowired
    private SysBindRoleAuthRepository bindRoleAuthRepository;
    @Autowired
    private SysBindAuthUriRepository bindAuthUriRepository;

    @Override
    public List<AuthDto> findAuths() {
        List<SysAuthPo> auths = authRepository.findAll();
        if (CollectionUtils.isEmpty(auths)) {
            return Lists.newArrayList();
        }
        return auths.stream().map(auth -> {
            AuthDto authDto = new AuthDto();
            BeanUtils.copyProperties(auth ,authDto);
            return authDto;
        }).collect(Collectors.toList());
    }

    @Override
    public AuthDto findAuthById(Long id) {
        SysAuthPo auth = authRepository.findById(id).orElse(null);
        if (auth == null) {
            return null;
        }
        AuthDto authDto = new AuthDto();
        BeanUtils.copyProperties(auth ,authDto);
        return authDto;
    }

    @Override
    public Long addAuth(AuthDto authDto) {
        SysAuthPo auth = authRepository.findByCode(authDto.getCode());
        Vct520Exception.throwIfTrue(auth != null, "权限Code已存在：" + authDto.getCode());
        auth = new SysAuthPo();
        BeanUtils.copyProperties(authDto, auth);
        return authRepository.save(auth).getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAuth(Long id, AuthDto authDto) {
        SysAuthPo auth = authRepository.findById(id).orElse(null);
        Vct520Exception.throwIfEmpty(auth, "权限不存在");
        if (!auth.getCode().equals(authDto.getCode())) {
            Vct520Exception.throwIfTrue(authRepository.findByCode(authDto.getCode()) != null,
                    "权限Code已存在：" + authDto.getCode());
        }
        BeanUtils.copyProperties(authDto, auth, "id");
        authRepository.save(auth);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteAuth(Long id) {
        SysAuthPo auth = authRepository.findById(id).orElse(null);
        Vct520Exception.throwIfEmpty(auth, "权限不存在");
        Vct520Exception.throwIfTrue(CollectionUtils.isNotEmpty(bindAuthGroupAuthRepository.findByAuthId(id)),
                "有权限组绑定了该权限，请先确认并解绑");
        Vct520Exception.throwIfTrue(CollectionUtils.isNotEmpty(bindRoleAuthRepository.findByAuthId(id)),
                "有角色绑定了该权限，请先确认并解绑");
        authRepository.delete(auth);
        bindAuthUriRepository.deleteByAuthId(id);
        return true;
    }
}
